import os
import logging
from flask import Flask, send_from_directory
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 导入扩展实例
from app.extensions import db, jwt, cors, swagger

def create_app(config_name=None):
    """应用工厂函数"""
    # 确定配置名称
    if config_name is None:
        config_name = os.environ.get('FLASK_ENV', 'development')
    
    # 导入配置
    from app.config import config
    
    # 设置静态文件夹为项目根目录的static
    static_folder = os.path.join(os.path.dirname(__file__), '..', 'static')
    app = Flask(__name__, static_folder=static_folder)
    
    # 禁用URL严格斜杠检查，避免308重定向
    app.url_map.strict_slashes = False
    
    # 加载配置
    app.config.from_object(config[config_name])
    
    # 初始化配置
    config[config_name].init_app(app)
    
    # 初始化扩展
    initialize_extensions(app)
    
    # 注册蓝图
    register_blueprints(app)
    
    # 初始化数据库
    initialize_database(app)
    
    # 注册路由
    register_routes(app)
    
    # 配置静态文件路由
    configure_static_routes(app)
    
    # 配置日志
    configure_logging(app)
    
    # 注册命令行
    from . import commands
    commands.init_app(app)
    
    return app


def initialize_extensions(app):
    """初始化Flask扩展"""
    try:
        # 初始化数据库
        db.init_app(app)
        
        # 初始化JWT
        jwt.init_app(app)
        
        # 初始化CORS
        cors.init_app(app, origins=app.config.get("CORS_ORIGINS", "*"))
        
        # 初始化Swagger，使用自定义模板和配置
        from flasgger import Swagger
        from app.config.swagger_config import SWAGGER_TEMPLATE, SWAGGER_CONFIG
        Swagger(app, template=SWAGGER_TEMPLATE, config=SWAGGER_CONFIG)
        
        app.logger.info("✅ Flask扩展初始化完成")
        
    except Exception as e:
        app.logger.error(f"❌ Flask扩展初始化失败: {e}")
        raise


def register_blueprints(app):
    """在app上注册所有的蓝图"""
    try:
        # 注册API蓝图
        from app.api import api_bp
        app.register_blueprint(api_bp, url_prefix='/api')
        
        # 注册微信支付回调蓝图
        from app.wx_payment import wx_payment_bp
        
        app.logger.info("✅ 蓝图注册完成")
        
    except ImportError as e:
        app.logger.error(f"❌ 蓝图注册失败: {e}")


def initialize_database(app):
    """初始化数据库"""
    try:
        with app.app_context():
            # 导入所有模型
            from app.models import (
                user, venue, activity, banner, admin, payment, device,
                user_attribute, user_relation, order, payment_config, checkin_record,
                device_api_config
            )
            
            # 创建数据库表
            db.create_all()
            
            if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
                app.logger.info("✅ 数据库表初始化完成")
                
    except Exception as e:
        if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
            app.logger.warning(f"⚠️ 数据库表初始化警告: {e}")


def register_routes(app):
    """注册基础路由"""
    
    @app.route('/health')
    def health_check():
        """健康检查接口"""
        return {
            'status': 'ok', 
            'message': '服务运行正常',
            'version': '1.0.0',
            'environment': app.config.get('FLASK_ENV', 'development')
        }, 200

    @app.route('/')
    def index():
        """根路径"""
        return {
            'message': '体育场馆预约系统API',
            'version': '1.0.0',
            'docs': '/apidocs/',
            'health': '/health',
            'admin_login': '/api/v1/admin/login'
        }

    @app.errorhandler(404)
    def not_found(error):
        """404错误处理"""
        return {
            'code': 404,
            'message': '接口不存在'
        }, 404

    @app.errorhandler(500)
    def internal_error(error):
        """500错误处理"""
        app.logger.error(f"服务器内部错误: {error}")
        return {
            'code': 500,
            'message': '服务器内部错误'
        }, 500


def configure_static_routes(app):
    """配置静态文件路由"""
    
    
    @app.route('/static/uploads/<path:subpath>')
    def uploaded_file(subpath):
        """提供上传文件的访问"""
        upload_folder = app.config.get('UPLOAD_FOLDER', 'uploads')
        # 分离目录和文件名
        if '/' in subpath:
            directory, filename = subpath.rsplit('/', 1)
            return send_from_directory(os.path.join(upload_folder, directory), filename)
        else:
            return send_from_directory(upload_folder, subpath)
    
    @app.route('/uploads/<path:subpath>')
    def uploads_file(subpath):
        """提供上传文件的访问（兼容旧路径）"""
        upload_folder = app.config.get('UPLOAD_FOLDER', 'uploads')
        # 分离目录和文件名
        if '/' in subpath:
            directory, filename = subpath.rsplit('/', 1)
            return send_from_directory(os.path.join(upload_folder, directory), filename)
        else:
            return send_from_directory(upload_folder, subpath)


def configure_logging(app):
    """配置日志"""
    if not app.debug and not app.testing:
        # 确保日志目录存在
        log_dir = os.path.dirname(app.config.get('LOG_FILE', 'logs/app.log'))
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        
        # 配置日志格式
        logging.basicConfig(
            level=getattr(logging, app.config.get('LOG_LEVEL', 'INFO')),
            format=app.config.get('LOG_FORMAT', '%(asctime)s - %(name)s - %(levelname)s - %(message)s'),
            handlers=[
                logging.FileHandler(app.config.get('LOG_FILE', 'logs/app.log')),
                logging.StreamHandler()
            ]
        )